package com.leetcode;

import lombok.SneakyThrows;

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 1226. 哲学家进餐
 */
public class DiningPhilosophers {

    //1个Fork视为1个ReentrantLock，5个叉子即5个ReentrantLock，将其都放入数组中
    private final ReentrantLock[] lockList = {new ReentrantLock(),
            new ReentrantLock(),
            new ReentrantLock(),
            new ReentrantLock(),
            new ReentrantLock()};

    //限制最多只有4个哲学家去持有叉子
    private final Semaphore eatLimit = new Semaphore(4);

    public DiningPhilosophers() {
    }

    @SneakyThrows
    public void wantsToEat(int philosopher,
                           Runnable pickLeftFork,
                           Runnable pickRightFork,
                           Runnable eat,
                           Runnable putLeftFork,
                           Runnable putRightFork){

        int leftFork = (philosopher + 1) % 5;//左边叉子的编号

        eatLimit.acquire();//限制的人数-1

        lockList[leftFork].lock();  //拿起左边的叉子
        lockList[philosopher].lock(); //拿起右边的叉子

        pickLeftFork.run();
        pickRightFork.run();

        eat.run();

        putLeftFork.run();
        putRightFork.run();

        lockList[leftFork].unlock();
        lockList[philosopher].unlock();

        eatLimit.release();




    }
}
